package com.business.exam.service.impl;

import com.business.exam.domain.ExamQbCategory;
import com.business.exam.domain.ExamQbKnownledgeLabel;
import com.business.exam.domain.TextContent;
import com.business.exam.domain.enums.QuestionTypeEnum;
import com.business.exam.domain.question.*;
import com.business.exam.mapper.QuestionMapper;
import com.business.exam.mapper.TextContentMapper;
import com.business.exam.service.IQuestionService;
import com.business.exam.utils.ExamUtil;
import com.business.exam.utils.HtmlUtil;
import com.business.exam.utils.JsonUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class QuestionServiceImpl implements IQuestionService {
    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private TextContentMapper textContentMapper;


    @Override
    public List<QuestionResponseVM> page(QuestionPageRequestVM requestVM) {
        List<QuestionResponseVM> resultList =  questionMapper.findDataListForPage(requestVM);
        if (!CollectionUtils.isEmpty(resultList)) {
            resultList.forEach(q -> {
                q.setScore(ExamUtil.scoreToVM(Integer.valueOf(q.getScore())));
                TextContent textContent = textContentMapper.selectByPrimaryKey(q.getInfoTextContentId());
                QuestionObject questionObject = JsonUtil.toJsonObject(textContent.getContent(), QuestionObject.class);
                String clearHtml = HtmlUtil.clear(questionObject.getTitleContent());
                q.setShortTitle(clearHtml);
            });
        }
        return resultList;
    }

    @Override
    public QuestionEditRequestVM getQuestionEditRequestVM(Integer questionId) {
        QuestionPageRequestVM requestVM = new QuestionPageRequestVM();
        requestVM.setId(questionId);
        //题目映射
        List<Question> questionList = questionMapper.findDataList(requestVM);
        if (!CollectionUtils.isEmpty(questionList)) {
            return getQuestionEditRequestVM(questionList.get(0));
        } else {
            return null;
        }
    }

    @Override
    public QuestionEditRequestVM getQuestionEditRequestVM(Question question) {
        //题目映射
        TextContent questionInfoTextContent = textContentMapper.selectByPrimaryKey(question.getInfoTextContentId());
        QuestionObject questionObject = JsonUtil.toJsonObject(questionInfoTextContent.getContent(), QuestionObject.class);
        QuestionEditRequestVM questionEditRequestVM = new QuestionEditRequestVM();
        BeanUtils.copyProperties(question, questionEditRequestVM);
        questionEditRequestVM.setTitle(questionObject.getTitleContent());

        //答案
        QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(question.getQuestionType());
        switch (questionTypeEnum) {
            case SingleChoice:
            case TrueFalse:
                questionEditRequestVM.setCorrect(question.getCorrect());
                break;
            case MultipleChoice:
                questionEditRequestVM.setCorrectArray(ExamUtil.contentToArray(question.getCorrect()));
                break;
            case GapFilling:
                List<String> correctContent = questionObject.getQuestionItemObjects().stream().map(d -> d.getContent()).collect(Collectors.toList());
                questionEditRequestVM.setCorrectArray(correctContent);
                break;
            case ShortAnswer:
                questionEditRequestVM.setCorrect(questionObject.getCorrect());
                break;
            default:
                break;
        }
        questionEditRequestVM.setScore(ExamUtil.scoreToVM(question.getScore()));
        questionEditRequestVM.setAnalyze(questionObject.getAnalyze());

        //题目项映射
        List<QuestionEditItemVM> editItems = questionObject.getQuestionItemObjects().stream().map(o -> {
            QuestionEditItemVM questionEditItemVM = new QuestionEditItemVM();
            BeanUtils.copyProperties(o, questionEditItemVM);
            if (o.getScore() != null) {
                questionEditItemVM.setScore(ExamUtil.scoreToVM(o.getScore()));
            }
            return questionEditItemVM;
        }).collect(Collectors.toList());
        questionEditRequestVM.setItems(editItems);
        return questionEditRequestVM;
    }

    @Override
    @Transactional
    public Question insertFullQuestion(QuestionEditRequestVM model, Integer userId) {
        Date now = new Date();
        //题干、解析、选项等 插入
        TextContent infoTextContent = new TextContent();
        infoTextContent.setCreateTime(now);
        setQuestionInfoFromVM(infoTextContent, model);
        textContentMapper.insert(infoTextContent);

        Question question = new Question();
        question.setSubjectId(model.getSubjectId());
        question.setGradeLevel(model.getGradeLevel());
        question.setCreateTime(now);
        question.setQuestionType(model.getQuestionType());
        question.setStatus(1);//1表示正常
        question.setCorrectFromVM(model.getCorrect(), model.getCorrectArray());
        question.setScore(ExamUtil.scoreFromVM(model.getScore()));
        question.setDifficult(model.getDifficult());
        question.setInfoTextContentId(infoTextContent.getId());
        question.setCreateUser(userId);
        question.setDeleted(false);
        questionMapper.insertSelective(question);
        return question;
    }

    @Override
    @Transactional
    public Question updateFullQuestion(QuestionEditRequestVM model) {
        Question question = questionMapper.selectByPrimaryKey(model.getId());
        question.setSubjectId(model.getSubjectId());
        question.setGradeLevel(model.getGradeLevel());
        question.setScore(ExamUtil.scoreFromVM(model.getScore()));
        question.setDifficult(model.getDifficult());
        question.setCorrectFromVM(model.getCorrect(), model.getCorrectArray());
        questionMapper.updateByPrimaryKeySelective(question);

        //题干、解析、选项等 更新
        TextContent infoTextContent = textContentMapper.selectByPrimaryKey(question.getInfoTextContentId());
        setQuestionInfoFromVM(infoTextContent, model);
        textContentMapper.updateByPrimaryKey(infoTextContent);
        return question;
    }

    @Override
    public Question selectById(Integer id) {
        Question question = questionMapper.selectByPrimaryKey(id);
        return question;
    }

    @Override
    public void updateByPrimaryKeySelective(Question question) {
        questionMapper.updateByPrimaryKeySelective(question);
    }

    @Override
    public Integer selectCategoryIdByContent(String gradeLevel) {
        ExamQbCategory examQbCategory = questionMapper.selectCategoryIdByContent(gradeLevel);
        if(examQbCategory!=null){
            return Integer.parseInt(String.valueOf(examQbCategory.getCategoryId()));
        }
        return null;
    }

    @Override
    public Integer selectKnowledgeIdByContent(String subjectId) {
        ExamQbKnownledgeLabel examQbKnownledgeLabel = questionMapper.selectKnowledgeIdByContent(subjectId);
        if(examQbKnownledgeLabel!=null){
            return Integer.parseInt(String.valueOf(examQbKnownledgeLabel.getLabelId()));
        }
        return null;
    }
    /**
     * 按照题库分类查询所包含的各题型个数
     * @param model
     * @return
     */
    @Override
    public Map<String, Object> selectTotalQuestion(QuestionPageRequestVM model) {
        List<Map<String, Object>> list = questionMapper.selectTotalQuestion(model);
        Map<String, Object> map = new HashMap<>();
        if(null!=list){
            for (int i = 0; i < list.size(); i++) {
                Map<String, Object> param = list.get(i);
                int questionType = Integer.parseInt(String.valueOf(param.get("question_type")));
                int count = Integer.parseInt(String.valueOf(param.get("count")));
                if(questionType==1){
                    map.put("singleChoice",count);
                } else if (questionType==2) {
                    map.put("multipleChoice",count);
                } else if (questionType==3) {
                    map.put("trueFalse",count);
                } else if (questionType==4) {
                    map.put("gapFilling",count);
                } else if (questionType==5) {
                    map.put("shortAnswer",count);
                }
            }
        }
        return map;
    }

    public void setQuestionInfoFromVM(TextContent infoTextContent, QuestionEditRequestVM model) {
        List<QuestionItemObject> itemObjects = model.getItems().stream().map(i ->
                {
                    QuestionItemObject item = new QuestionItemObject();
                    item.setPrefix(i.getPrefix());
                    item.setContent(i.getContent());
                    item.setItemUuid(i.getItemUuid());
                    item.setScore(ExamUtil.scoreFromVM(i.getScore()));
                    return item;
                }
        ).collect(Collectors.toList());
        QuestionObject questionObject = new QuestionObject();
        questionObject.setQuestionItemObjects(itemObjects);
        questionObject.setAnalyze(model.getAnalyze());
        questionObject.setTitleContent(model.getTitle());
        questionObject.setCorrect(model.getCorrect());
        infoTextContent.setContent(JsonUtil.toJsonStr(questionObject));
    }
}
